package battleship.boat;

import java.util.Arrays;

import battleship.Setup;
import battleship.field.Field;
import battleship.player.Player;

public class Boat {
	
	private int[][] positions; //positions of the boat: ((y,x), (y,x))
	private String name; //name of the boat, defined in BoatEnum
	private boolean[] hit; //false when the position is not hit
	private int length; //length of the boat, used in for loops
	
	
	
	public Boat(BoatEnum boat){
		this.name = boat.getName();
		this.length = boat.getLength();
		this.positions = new int[length][2];
		this.hit = new boolean[length];
		initialize();
	}
	
	public boolean getVertical()
	{
		if(positions[0][0] == positions[1][0]) return false;
		return true;
	}
	
	
	public int[][] getPositions(){ //returns positions, used for hitDetection
		return positions;
	}
	
	public String getName(){ //returns name, used for printing boat name
		return name;
	}
	
	public boolean[] getHit(){ //return hits, (true, false, true)...
		return hit;
	}
	
	public int getLength(){ //returns length
		return length;
	}
	
	public boolean getSetup()
	{
	
		return !(positions[0][0] == -1);
	
	}
	
	public void initialize() {
		for (int pos = 0; pos < length; pos++){
			for (int posXY = 0; posXY < positions[pos].length; posXY++){
				positions[pos][posXY] = -1;
				hit[pos] = false;
			}
		}
	}
	
	public boolean setPosition(Player player, int x, int y, boolean vert){ //set the position for the player
		if (outOfBoundsDetection(x, y, vert, player)) {
			return false; //was not set
		}
		if (collisionDetection(x, y, vert, player)) {
			return false; //boat collides with another
		}
		
		
		
		/* make permanent positions */
		int arrayX = x;
		int arrayY = y;
		
		for(int pos = 0; pos < length; pos++){
			if(vert){
				positions[pos] = new int[] {arrayY + pos, arrayX}; 
			}
			else {
				positions[pos] = new int[] {arrayY, arrayX + pos};
			}
		}
		
		return true;
	}
	
	public boolean getSunk(){
		for(int hits = 0; hits < hit.length; hits++){
			if(!hit[hits]){

				return false;
			}
		}
		return true;
	}
	
	public String toString(){
		StringBuilder sb = new StringBuilder();
		
		int initX = positions[0][1];
		int initY = positions[0][0];
		
		sb.append(Setup.getPositionMap()[initY]);
		sb.append(String.valueOf(initX + 1));
		sb.append(getVertical()?"v":"h");
		
		return sb.toString();
	}
	
	public boolean collisionDetection(int x, int y, boolean vert, Player player){//returns false when nothing is colliding
		int [][] tempPositions = new int[length][2];
		
		/* make temporary positions */
		int arrayX = x;
		int arrayY = y;
		for(int pos = 0; pos < length; pos++){
			if(vert){
				tempPositions[pos] = new int[] {arrayY + pos, arrayX}; 
			}
			else {
				tempPositions[pos] = new int[] {arrayY, arrayX + pos};
			}
		}
		
		for (int boat1Pos = 0; boat1Pos < tempPositions.length; boat1Pos++){ //go through every pos of the boat
			for (int boat2 = 0; boat2 < player.getField().getBoats().length; boat2++){ //go through every boat
				for(int boat2Pos = 0; boat2Pos < player.getField().getBoats()[boat2].length; boat2Pos++){ //go through every pos of these boats
					if (boat2Pos == 0 && Arrays.equals(player.getField().getBoats()[boat2].positions[boat2Pos], new int[] { -1, -1})){
						if(!(boat2 == player.getField().getBoats().length -1)) { //make sure we dont get out of bounds
							boat2++;
							boat2Pos = -1; // the for loop automatically adds one
						}
						
					}
					else {
						if(Arrays.equals(player.getField().getBoats()[boat2].positions[boat2Pos], tempPositions[boat1Pos])){
							// already a boat here
							return true;
						}
					}
				}
			}
		}
		return false;
	}
	
	private boolean outOfBoundsDetection(int x, int y, boolean vert, Player player) {
		
		int [][] tempPositions = new int[length][2];
		
		/* make temporary positions */
		int arrayX = x;
		int arrayY = y;
		for(int pos = 0; pos < length; pos++){
			if(vert){
				tempPositions[pos] = new int[] {arrayY + pos, arrayX}; 
			}
			else {
				tempPositions[pos] = new int[] {arrayY, arrayX + pos};
			}
		}
		
		for (int tempPos = 0; tempPos < length; tempPos++){
			if(tempPositions[tempPos][0] >= Field.getHeight() || tempPositions[tempPos][0] < 0
					|| tempPositions[tempPos][1] >= Field.getWidth() || tempPositions[tempPos][1] < 0){
				return true;
			}
		}
		return false;
		
	}
	
	public void setHit(int[] position){ //used to set where the boat got hit
		if(isHit(position)){
			for(int i = 0; i < length; i++){
				if(Arrays.equals(position, positions[i])) {
					hit[i] = true;
					break;
				}
			}
		}
	}
	
	/**
	 * checks if the boat exists on this position
	 * @param position the position where you think the boat is at
	 * @return true if the boat is at this position, false if not
	 */
	public boolean isHit(int[] position){//used to check if this position exists within the boat
		for(int i = 0; i < length; i++){
			if(Arrays.equals(position, positions[i])) { //if(position == positions[i]){
				return true;
			}
		}
		return false;
	
	}
		
}
